package com.csaba.db.wizards;

import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWizard;

import com.csaba.db.Activator;
import com.csaba.db.DatabaseManager;
import com.csaba.util.LoggerHelper;

/**
 * This is a sample new wizard. Its role is to create a new file 
 * resource in the provided container. If the container resource
 * (a folder or a project) is selected in the workspace 
 * when the wizard is opened, it will accept it as the target
 * container. The wizard creates one file with the extension
 * "mpe". If a sample multi-page editor (also available
 * as a template) is registered for the same extension, it will
 * be able to open it.
 */

public class NewDBWizzard extends Wizard implements INewWizard
{
	private final static Logger logger = LoggerHelper.getDefaultLogger();
	private NewDBWizzardPage page;

	/**
	 * Constructor for NewDBWizzard.
	 */
	public NewDBWizzard()
	{
		super();
		setNeedsProgressMonitor(true);
	}

	/**
	 * Adding the page to the wizard.
	 */

	@Override
	public void addPages()
	{
		page = new NewDBWizzardPage();
		addPage(page);
	}

	/**
	 * This method is called when 'Finish' button is pressed in
	 * the wizard. We will create an operation and run it
	 * using wizard as execution context.
	 */
	@Override
	public boolean performFinish()
	{
		final String userName = page.getUserName();
		final String password = page.getPassword();
		final IRunnableWithProgress op = new IRunnableWithProgress()
		{
			public void run( final IProgressMonitor monitor ) throws InvocationTargetException, InterruptedException
			{
				try
				{
					doFinish(userName, password, monitor);
				}
				catch ( final CoreException e )
				{
					throw new InvocationTargetException(e);
				}
				finally
				{
					monitor.done();
				}
			}
		};
		try
		{
			getContainer().run(true, false, op);
		}
		catch ( final InterruptedException e )
		{
			return false;
		}
		catch ( final InvocationTargetException e )
		{
			final Throwable realException = e.getTargetException();
			MessageDialog.openError(getShell(), "Error", "Exception occured: " + realException.getMessage());
			logger.log(Level.SEVERE, "Error craeting new database.", realException);
			return false;
		}
		return true;
	}

	/**
	 * The worker method. It will find the container, create the
	 * file if missing or just replace its contents, and open
	 * the editor on the newly created file.
	 * @throws InterruptedException 
	 */

	private void doFinish( final String userName, final String password, final IProgressMonitor monitor )
			throws CoreException, InterruptedException
	{
		// create enclosing project
		monitor.beginTask("Creating " + userName, 4);
		final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		final IProject project = root.getProject(userName);
		if ( project != null && project.exists() )
		{
			Activator.throwCoreException("User \"" + userName + "\" already exists.");
		}

		if ( project == null )
		{
			Activator.throwCoreException("Cannot create project: " + userName);
		}

		project.create(monitor);
		project.open(monitor);

		final DatabaseManager dbm = DatabaseManager.getInstance();
		// close any open project
		monitor.worked(1);
		monitor.setTaskName("Closing active database...");

		if ( dbm.hasActiveDatabase() )
		{
			dbm.closeActiveDatabase(monitor);
		}

		// initialize database
		monitor.worked(1);
		monitor.setTaskName("Initializing the database...");
		DatabaseManager.getInstance().initializeDB(project, password);

		// FIXME refresh view 
		monitor.worked(1);
		monitor.setTaskName("Refresh views...");

		/*
		getShell().getDisplay().asyncExec(new Runnable()
		{
			public void run()
			{
				final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
				try
				{
					IDE.openEditor(page, file, true);
				}
				catch ( final PartInitException e )
				{
				}
			}
		});*/
		monitor.worked(1);
	}

	/**
	 * Cannot do anything with the selection here.
	 * @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
	 */
	public void init( final IWorkbench workbench, final IStructuredSelection selection )
	{
		//do nothing
	}
}